/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.googlecode.mindlistening.graph;

import java.awt.event.MouseEvent;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JComponent;
import javax.swing.JFrame;
import org.apache.commons.io.IOUtils;
import org.ektorp.CouchDbConnector;
import org.ektorp.ViewQuery;
import org.ektorp.ViewResult;
import org.ektorp.ViewResult.Row;
import org.ektorp.http.HttpClient;
import org.ektorp.http.RestTemplate;
import prefuse.Display;
import prefuse.Visualization;
import prefuse.action.ActionList;
import prefuse.action.RepaintAction;
import prefuse.action.assignment.ColorAction;
import prefuse.action.layout.CircleLayout;
import prefuse.action.layout.RandomLayout;
import prefuse.action.layout.graph.ForceDirectedLayout;
import prefuse.action.layout.graph.FruchtermanReingoldLayout;
import prefuse.action.layout.graph.RadialTreeLayout;
import prefuse.action.layout.graph.SquarifiedTreeMapLayout;
import prefuse.activity.Activity;
import prefuse.controls.DragControl;
import prefuse.controls.FocusControl;
import prefuse.controls.PanControl;
import prefuse.controls.ZoomControl;
import prefuse.data.Graph;
import prefuse.data.Table;
import prefuse.data.Tuple;
import prefuse.data.io.DataIOException;
import prefuse.data.io.GraphMLReader;
import prefuse.render.DefaultRendererFactory;
import prefuse.render.LabelRenderer;
import prefuse.util.ColorLib;
import prefuse.visual.VisualItem;

/**
 *
 * @author ryan
 */
public class PrefuseGraph {

    Visualization vis;

    public void showGraph(HttpClient couchHttpClient, String couchDbName) {
        JFrame frame = new JFrame("Topic Graph");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(getDisplay(couchHttpClient, couchDbName));
        frame.pack();
        frame.setVisible(true);
        vis.run("color");
        vis.run("layout");


    }

    public JComponent getDisplay(HttpClient couchHttpClient, String couchDbName) {
        Graph g = createGraphFromGraphMLView(couchHttpClient, couchDbName);

        vis = new Visualization();
        vis.add("graph", g);
        vis.setInteractive("graph.edges", null, false);

        LabelRenderer r = new LabelRenderer("name");
        r.setRoundedCorner(8,8);
        vis.setRendererFactory(new DefaultRendererFactory(r));



        ColorAction fill = new ColorAction("graph.nodes",
                VisualItem.FILLCOLOR, ColorLib.rgb(215,215,215));
        ColorAction text = new ColorAction("graph.nodes",
                VisualItem.TEXTCOLOR, ColorLib.gray(0));
        ColorAction edges = new ColorAction("graph.edges",
                VisualItem.STROKECOLOR, ColorLib.gray(200));
        ActionList color = new ActionList();
        color.add(fill);
        color.add(text);
        color.add(edges);

        ActionList layout = new ActionList(Activity.INFINITY);
        layout.add(new ForceDirectedLayout("graph"));
        //layout.add(new CircleLayout("graph"));
        //layout.add(new ForceDirectedLayout("graph"));
        //layout.add(new RandomLayout("graph"));
        layout.add(new RepaintAction());

        vis.putAction("layout", layout);
        vis.putAction("color", color);

        Display display = new Display(vis);
        display.setSize(720, 500);
        display.addControlListener(new DragControl());
        display.addControlListener(new PanControl());
        display.addControlListener(new ZoomControl());
        display.addControlListener(new FocusControl(2) {
            @Override
            public void itemClicked(VisualItem item, MouseEvent e) {
                //System.out.println("Double click");
                //String id = item.getString("id");
                //System.out.println("id: " + id);
                //item.getRow();

            }
        });


        return display;
    }



    public Graph createGraphFromGraphMLView(HttpClient couchHttpClient, String couchDbName) {
        RestTemplate t = new RestTemplate(couchHttpClient);
        InputStream is = t.get("/"+couchDbName+"/_design/tags/_list/graphml/by_id").getContent();

        

        try {
            //InputStream is = PrefuseGraph.class.getResourceAsStream("/graph.xml");
            //FileInputStream is = new FileInputStream();
            Graph g = new GraphMLReader().readGraph(is);
            return g;
        } catch (Exception ex) {
            Logger.getLogger(PrefuseGraph.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }

    }



    public Graph createGraph(CouchDbConnector wikiConnector) {
        Table nodes = new Table();
        nodes.addColumn("id", String.class);

        Table edges = new Table();
        edges.addColumn("from", String.class);
        edges.addColumn("to",   String.class);
        edges.addColumn("instanceof", Boolean.class);

        Graph g = new Graph(nodes, edges, true, "id", "from", "to");

        ViewQuery query = new ViewQuery()
                .designDocId("_design/tags")
                .viewName("by_id");
        ViewResult result = wikiConnector.queryView(query);
        for (Row r : result.getRows()) {
            String id = r.getId();
            int row = nodes.addRow();
            nodes.setString(row, "id", id);
            
        }



        return g;
    }

}
